package com.hzhc.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzhc.common.FileExcelUtil;
import com.hzhc.dto.UserDto;
import com.hzhc.entity.CarInfo;
import com.hzhc.entity.CompanyInfo;
import com.hzhc.entity.TowInfo;
import com.hzhc.enumBean.ResultUtilCodeEnum;
import com.hzhc.mapper.CompanyInfoMapper;
import com.hzhc.mapper.TowInfoMapper;
import com.hzhc.service.TowInfoService;
import com.hzhc.utils.EasypoiExcelUtils;
import com.hzhc.utils.ResultUtil;
import com.hzhc.utils.StringUtils;
import com.hzhc.vo.CarInfoVo;
import com.hzhc.vo.TowInfoVo;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * <p>
 * 拖挂信息 服务实现类
 * </p>
 *
 * @author 功不唐捐
 * @since 2024-12-18
 */
@Service
@RequiredArgsConstructor
public class TowInfoServiceImpl extends ServiceImpl<TowInfoMapper, TowInfo> implements TowInfoService {
    private final CompanyInfoMapper companyInfoMapper;

    @Override
    public ResultUtil<T> getTowNo(TowInfo towInfo) {
        QueryWrapper<TowInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("disable", 0);
        queryWrapper.eq("tow_no", towInfo.getTowNo());
        if (towInfo.getId() != null) {
            queryWrapper.ne("id", towInfo.getId());
        }
        TowInfo selectOne = baseMapper.selectOne(queryWrapper);
        if (selectOne != null) {
            return ResultUtil.build(ResultUtilCodeEnum.TOW_INFO_EXIST);
        }
        return ResultUtil.ok();
    }

    @Override
    public List<TowInfo> getList(Page<TowInfo> page, TowInfoVo vo) {
        IPage<TowInfo> pageList = baseMapper.getList(page, vo);
        return pageList.getRecords();
    }

    @Override
    public ResultUtil<T> addRet(TowInfo towInfo) {
        QueryWrapper<TowInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("disable", 0);
        queryWrapper.eq("tow_no", towInfo.getTowNo());
        if (towInfo.getId() != null) {
            queryWrapper.ne("id", towInfo.getId());
        }
        TowInfo selectOne = baseMapper.selectOne(queryWrapper);
        if (selectOne != null) {
            return ResultUtil.build(ResultUtilCodeEnum.TOW_INFO_EXIST);
        }
        towInfo.setCreateTime(LocalDateTime.now());
        boolean b = save(towInfo);
        return b ? ResultUtil.ok() : ResultUtil.fail();
    }

    @Override
    public ResultUtil<T> updateRet(TowInfo towInfo) {
        QueryWrapper<TowInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("disable", 0);
        queryWrapper.eq("tow_no", towInfo.getTowNo());
        if (towInfo.getId() != null) {
            queryWrapper.ne("id", towInfo.getId());
        }
        TowInfo selectOne = baseMapper.selectOne(queryWrapper);
        if (selectOne != null) {
            return ResultUtil.build(ResultUtilCodeEnum.TOW_INFO_EXIST);
        }
        towInfo.setUpdateTime(LocalDateTime.now());
        Boolean b = updateById(towInfo);
        return b ? ResultUtil.ok() : ResultUtil.fail();
    }

    @Override
    public ResultUtil<T> delTowInfo(TowInfo towInfo) {
        towInfo.setDisable(true);
        boolean b =updateById(towInfo);
        return b?ResultUtil.ok():ResultUtil.fail();
    }

    @Override
    public ResultUtil<T> importTowList(HttpServletRequest request, List<TowInfo> towList) {
        LocalDateTime currentTime = LocalDateTime.now();
        LambdaQueryWrapper<CompanyInfo> queryWrapper = new LambdaQueryWrapper<CompanyInfo>();
        queryWrapper.select(CompanyInfo::getId, CompanyInfo::getName, CompanyInfo::getNameSimple);
        List<CompanyInfo> result = companyInfoMapper.selectList(queryWrapper);
        QueryWrapper<TowInfo> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("disable", 0);
        List<TowInfo> towInfoList=new ArrayList<>(baseMapper.selectList(queryWrapper2));
        // 将CompanyInfo列表转换为Map以便快速查找
        Map<String, Long> nameToIdMap = new HashMap<>();
        for (CompanyInfo company : result) {
            nameToIdMap.put(company.getName(), company.getId());
            if (company.getNameSimple() != null) {
                nameToIdMap.put(company.getNameSimple(), company.getId());
            }
        }
        for (TowInfo tow : towList) {
            List<TowInfo> collect = towInfoList.stream().filter(s -> s.getTowNo().equals(tow.getTowNo())).collect(Collectors.toList());
            if (!collect.isEmpty()) {
                TowInfo towInfo = collect.get(0); // 取第一个匹配的 CarInfo
                String towInfoHdId = towInfo.getHdId(); // 获取 hdId

                // 拼接 hdId 到当前 car 的 hdId
                if (tow.getHdId() == null) {
                    tow.setHdId(towInfoHdId); // 如果当前 hdId 为空，直接设置
                } else {
                    tow.setHdId(tow.getHdId() + "," + towInfoHdId); // 否则进行拼接
                }
                tow.setId(towInfo.getId());
            }
            tow.setCreateTime(currentTime);
            // 根据 companyName 匹配 CompanyInfo 中的 id
            Long hdId = nameToIdMap.get(tow.getCompanyName());
            if (hdId != null) {
                if (tow.getHdId() == null) {
                    tow.setHdId(Long.toString(hdId)); // 如果当前 hdId 为空，直接设置
                } else {
                    tow.setHdId(tow.getHdId() + "," + hdId); // 否则进行拼接
                }
            } else {
                return ResultUtil.build(ResultUtilCodeEnum.DEFAULT_HDID);
            }
        }
        boolean b = saveOrUpdateBatch(towList);
        return b ? ResultUtil.ok() : ResultUtil.fail();
    }

    @Override
    public void exportTowFile(HttpServletRequest request, HttpServletResponse response, String exportExcelPath) {
        Map<String, Object> map = new HashMap<>();
        TemplateExportParams params = new TemplateExportParams(exportExcelPath);
        Workbook workbook = ExcelExportUtil.exportExcel(params, map);
        FileExcelUtil.downloadExcelIo(workbook, request, response, "车辆导入");
    }

    @Override
    public ResultUtil<List<TowInfoVo>> towUpload(UserDto user, MultipartFile file,String path) {
        List<TowInfoVo> list = new ArrayList<TowInfoVo>();
        List<String> towList = new ArrayList<String>();
        ResultUtil<List<TowInfoVo>> build = new ResultUtil<>();
        if (file != null) {
            try {
                List<TowInfoVo> planTowVos = EasypoiExcelUtils.importExcel(file, 0, 1, TowInfoVo.class);
                QueryWrapper<TowInfo> queryWrapper=new QueryWrapper<>();
                queryWrapper.eq("disable",0);
                List<TowInfo> towInfos = baseMapper.selectList(queryWrapper);
                for (TowInfoVo c:planTowVos) { //校验数据
                    if (ObjectUtil.isEmpty(c)|| StrUtil.isBlank(c.getTowNo())){
                        c.setErrorInfo("文件中有空数据;");
                        break;
                    }
                    String errorInfo = checkTow(towList, towInfos, c.getTowNo(),c.getCompanyName());

                    if("PC".equals(path)){
                        if (!StrUtil.isNotBlank(c.getCompanyName())){
                            errorInfo += "车队信息未填";
                        }
                    }
                    if (!StrUtil.isNotBlank(c.getTowWeight())){
                        errorInfo += "拖挂重量未填";
                    }
                    c.setErrorInfo(errorInfo);
                    List<TowInfo> matchedCarInfos = towInfos.stream()
                            .filter(s -> s.getTowNo().equals(c.getTowNo()))
                            .collect(Collectors.toList());

                    c.setTowList(matchedCarInfos);
                    list.add(c);
                }
                build = ResultUtil.build(list, ResultUtilCodeEnum.SUCCESS);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return build;
    }

    private String checkTow(List<String> towList, List<TowInfo> towInfos, String towNo,String companyName) {
        if (towNo == null || towNo.trim().isEmpty()) {
            return "拖挂号不能为空;";
        }

        // 检查拖挂号是否已经存在于列表中
        if (towList.contains(towNo)) {
            return "拖挂号重复;";
        }
        // 检查车牌号是否已经存在于 carInfoVos 列表中，两个条件车牌和公司同时存在不能成立

        if(StringUtils.isNotEmpty(towNo) && StringUtils.isNotEmpty(companyName)){
            List<CompanyInfo> companyInfos = companyInfoMapper.selectList(new QueryWrapper<CompanyInfo>().eq("disable", 0).eq("car_team_flag",1));

            if(companyInfos.size()>0){
                List<CompanyInfo> collect = companyInfos.stream().filter(s -> s.getName().equals(companyName) || s.getNameSimple().equals(companyName)).collect(Collectors.toList());
                if(collect.size()>0){
                    Long id=collect.get(0).getId();
                    boolean isExisting = towInfos.stream().anyMatch(item ->
                            towNo.equals(item.getTowNo()) && Arrays.asList(item.getHdId().split(",")).contains(String.valueOf(id)));
                    if (isExisting) {
                        return "该拖挂号在同一公司下已存在;";
                    }
                }else{
                    return "该车队名不存在";
                }
            }
        }

        // 添加到 carList 中，标记车牌号为唯一
        towList.add(towNo);
        return "";
    }
}
